--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Commit 59c0a60b3319857d7d331a2678b1dd5804f6dd72
Parents : 427c06b
Author : Mark Qvist <mark@unsigned.io>
Date : 2025-11-10T15:49:52+01:00
Reworked battery charge state detection for boards with only ADC-based PMU. Improved battery charge status info on display.
Changes
3 files changed, 53 insertions(+), 23 deletions(-)
Diff
diff --git a/Display.h b/Display.h
index ebc02fd..8ce8d1c 100644
--- a/Display.h
+++ b/Display.h
@@ -574,6 +574,9 @@ void draw_battery_bars(int px, int py) {
}
if (battery_state == BATTERY_STATE_CHARGING && !disable_charge_status) {
+ float battery_prog = battery_percent;
+ if (battery_prog > 85) { battery_prog = 84; }
+ if (charge_tick < battery_prog ) { charge_tick = battery_prog; }
battery_value = charge_tick;
charge_tick += 3;
if (charge_tick > 100) charge_tick = 0;
diff --git a/Makefile b/Makefile
index 637475c..12a5f27 100644
--- a/Makefile
+++ b/Makefile
@@ -204,13 +204,13 @@ upload-heltec32_v3:
arduino-cli upload -p /dev/ttyUSB0 --fqbn esp32:esp32:heltec_wifi_lora_32_V3
@sleep 1
rnodeconf /dev/ttyUSB0 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.heltec_wifi_lora_32_V3/RNode_Firmware.ino.bin)
- @sleep 3
- python ./Release/esptool/esptool.py --chip esp32-s3 --port /dev/ttyUSB0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 4MB 0x210000 ./Release/console_image.bin
+ #@sleep 3
+ #python ./Release/esptool/esptool.py --chip esp32-s3 --port /dev/ttyUSB0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 4MB 0x210000 ./Release/console_image.bin
upload-heltec32_v4:
- arduino-cli upload -p /dev/ttyACM1 --fqbn esp32:esp32:esp32s3
+ arduino-cli upload -p /dev/ttyACM0 --fqbn esp32:esp32:esp32s3
@sleep 1
- rnodeconf /dev/ttyACM1 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.esp32s3/RNode_Firmware.ino.bin)
+ rnodeconf /dev/ttyACM0 --firmware-hash $$(./partition_hashes ./build/esp32.esp32.esp32s3/RNode_Firmware.ino.bin)
#@sleep 3
#python ./Release/esptool/esptool.py --chip esp32-s3 --port /dev/ttyACM0 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size 4MB 0x210000 ./Release/console_image.bin
diff --git a/Power.h b/Power.h
index 66970d1..ca2b259 100644
--- a/Power.h
+++ b/Power.h
@@ -95,8 +95,19 @@
float bat_delay_v = 0;
float bat_state_change_v = 0;
#elif BOARD_MODEL == BOARD_HELTEC32_V3
- #define BAT_V_MIN 3.15
- #define BAT_V_MAX 4.3
+ // Unless we implement some real voodoo
+ // on these boards, we can't say with
+ // any certainty whether we are actually
+ // charging and have reached a charge
+ // complete state. The *only* data point
+ // we have to go from is the bus voltage.
+ // The BAT_V_CHG and BAT_V_FLOAT values
+ // are set high here to avoid the display
+ // indication confusingly flapping
+ // between charge completed, charging and
+ // discharging states.
+ #define BAT_V_MIN 3.05
+ #define BAT_V_MAX 4.0
#define BAT_V_CHG 4.48
#define BAT_V_FLOAT 4.33
#define BAT_SAMPLES 7
@@ -112,8 +123,8 @@
float bat_delay_v = 0;
float bat_state_change_v = 0;
#elif BOARD_MODEL == BOARD_HELTEC32_V4
- #define BAT_V_MIN 3.15
- #define BAT_V_MAX 4.3
+ #define BAT_V_MIN 3.05
+ #define BAT_V_MAX 4.0
#define BAT_V_CHG 4.48
#define BAT_V_FLOAT 4.33
#define BAT_SAMPLES 7
@@ -166,19 +177,28 @@
uint32_t last_pmu_update = 0;
uint8_t pmu_target_pps = 1;
int pmu_update_interval = 1000/pmu_target_pps;
+uint8_t pmu_charged_ascertain = 0;
uint8_t pmu_rc = 0;
+uint8_t pmu_sc = 0;
+float bat_delay_diff = 0;
+bool bat_diff_positive = false;
#define PMU_R_INTERVAL 5
+#define PMU_SCV_RESET_INTERVAL 3
void kiss_indicate_battery();
void measure_battery() {
#if BOARD_MODEL == BOARD_RNODE_NG_21 || BOARD_MODEL == BOARD_LORA32_V2_1 || BOARD_MODEL == BOARD_HELTEC32_V3 || BOARD_MODEL == BOARD_HELTEC32_V4 || BOARD_MODEL == BOARD_TDECK || BOARD_MODEL == BOARD_T3S3 || BOARD_MODEL == BOARD_HELTEC_T114 || BOARD_MODEL == BOARD_TECHO
battery_installed = true;
- battery_indeterminate = true;
+ #if BOARD_MODEL == BOARD_HELTEC32_V3 || BOARD_MODEL == BOARD_HELTEC32_V4
+ battery_indeterminate = false;
+ #else
+ battery_indeterminate = true;
+ #endif
#if BOARD_MODEL == BOARD_HELTEC32_V3
float battery_measurement = (float)(analogRead(pin_vbat)) * 0.0041;
#elif BOARD_MODEL == BOARD_HELTEC32_V4
- float battery_measurement = (float)(analogRead(pin_vbat)) * 0.0041;
+ float battery_measurement = (float)(analogRead(pin_vbat)) * 0.00418;
#elif BOARD_MODEL == BOARD_T3S3
float battery_measurement = (float)(analogRead(pin_vbat)) / 4095.0*6.7828;
#elif BOARD_MODEL == BOARD_HELTEC_T114
@@ -217,23 +237,23 @@ void measure_battery() {
if (battery_percent < 0.0) battery_percent = 0.0;
if (bat_samples_count%BAT_SAMPLES == 0) {
- float bat_delay_diff = bat_state_change_v-battery_voltage;
- if (bat_delay_diff < 0) { bat_delay_diff *= -1; }
+ pmu_sc++;
+ bat_delay_diff = battery_voltage-bat_state_change_v;
if (battery_voltage < bat_delay_v && battery_voltage < BAT_V_FLOAT) {
if (bat_voltage_dropping == false) {
- if (bat_delay_diff > 0.008) {
+ if (bat_delay_diff < -0.008) {
bat_voltage_dropping = true;
bat_state_change_v = battery_voltage;
- // SerialBT.printf("STATE CHANGE to DISCHARGE at delta=%.3fv. State change v is now %.3fv.\n", bat_delay_diff, bat_state_change_v);
}
+ } else {
+ if (pmu_sc%PMU_SCV_RESET_INTERVAL == 0) { bat_state_change_v = battery_voltage; }
}
} else {
if (bat_voltage_dropping == true) {
if (bat_delay_diff > 0.01) {
bat_voltage_dropping = false;
bat_state_change_v = battery_voltage;
- // SerialBT.printf("STATE CHANGE to CHARGE at delta=%.3fv. State change v is now %.3fv.\n", bat_delay_diff, bat_state_change_v);
}
}
}
@@ -242,12 +262,19 @@ void measure_battery() {
}
if (bat_voltage_dropping && battery_voltage < BAT_V_FLOAT) {
+ // if (battery_state != BATTERY_STATE_DISCHARGING) { SerialBT.printf("STATE CHANGE to DISCHARGING at delta=%.3fv. State change v is now %.3fv.\n", bat_delay_diff, bat_state_change_v); }
battery_state = BATTERY_STATE_DISCHARGING;
+ pmu_charged_ascertain = 0;
} else {
- if (battery_percent < 100.0) {
- battery_state = BATTERY_STATE_CHARGING;
- } else {
- battery_state = BATTERY_STATE_CHARGED;
+ if (pmu_charged_ascertain < 8) { pmu_charged_ascertain++; }
+ else {
+ if (battery_percent < 100.0) {
+ // if (battery_state != BATTERY_STATE_CHARGING) { SerialBT.printf("STATE CHANGE to CHARGING at delta=%.3fv. State change v is now %.3fv.\n", bat_delay_diff, bat_state_change_v); }
+ battery_state = BATTERY_STATE_CHARGING;
+ } else {
+ // if (battery_state != BATTERY_STATE_CHARGED) { SerialBT.printf("STATE CHANGE to CHARGED at delta=%.3fv. State change v is now %.3fv.\n", bat_delay_diff, bat_state_change_v); }
+ battery_state = BATTERY_STATE_CHARGED;
+ }
}
}
@@ -256,11 +283,11 @@ void measure_battery() {
#endif
// if (bt_state == BT_STATE_CONNECTED) {
- // SerialBT.printf("\nBus voltage %.3fv. Unfiltered %.3fv.", battery_voltage, bat_v_samples[BAT_SAMPLES-1]);
+ // SerialBT.printf("\nBus voltage %.3fv. Unfiltered %.3fv. Diff %.3f", battery_voltage, bat_v_samples[BAT_SAMPLES-1], bat_delay_diff);
// if (bat_voltage_dropping) { SerialBT.printf("\n Voltage is dropping. Percentage %.1f%%.", battery_percent); }
// else { SerialBT.printf("\n Voltage is not dropping. Percentage %.1f%%.", battery_percent); }
- // if (battery_state == BATTERY_STATE_DISCHARGING) { SerialBT.printf("\n Battery discharging. delay_v %.3fv", bat_delay_v); }
- // if (battery_state == BATTERY_STATE_CHARGING) { SerialBT.printf("\n Battery charging. delay_v %.3fv", bat_delay_v); }
+ // if (battery_state == BATTERY_STATE_DISCHARGING) { SerialBT.printf("\n Battery discharging. delay_v %.3fv\nState change at %.3fv", bat_delay_v, bat_state_change_v); }
+ // if (battery_state == BATTERY_STATE_CHARGING) { SerialBT.printf("\n Battery charging. delay_v %.3fv\nState change at %.3fv", bat_delay_v, bat_state_change_v); }
// if (battery_state == BATTERY_STATE_CHARGED) { SerialBT.print("\n Battery is charged."); }
// SerialBT.print("\n");
// }
@@ -389,7 +416,7 @@ bool init_pmu() {
return true;
#elif BOARD_MODEL == BOARD_HELTEC32_V4
pinMode(pin_ctrl,OUTPUT);
- digitalWrite(pin_ctrl, LOW);
+ digitalWrite(pin_ctrl, HIGH);
return true;
#elif BOARD_MODEL == BOARD_HELTEC_T114
pinMode(pin_ctrl,OUTPUT);
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────